package com.yunyao.web.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.yunyao.common.dto.SaleContractDto;
import com.yunyao.common.dto.excel.ContractExcelDto;
import com.yunyao.common.dto.excel.ContractMaterialExcelDto;
import com.yunyao.common.web.util.PageResult;
import com.yunyao.common.web.util.YResult;
import com.yunyao.framework.dto.file.FileInfoDto;
import com.yunyao.framework.dto.sale.SaleContractApprovalDto;
import com.yunyao.framework.dto.sale.SaleContractDeletedDto;
import com.yunyao.framework.dto.sale.SaleContractSaveDto;
import com.yunyao.framework.dto.sale.SaleContractSubmitApprovalDto;
import com.yunyao.framework.service.SaleContractService;
import com.yunyao.framework.vo.sale.SaleContractInfoVO;
import com.yunyao.framework.vo.sale.SaleContractPurchaseInfoVO;
import com.yunyao.framework.vo.sale.SaleContractVO;
import com.yunyao.web.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author xingjishuai
 * @date 2024-07-11
 */
@RestController
@RequestMapping("/saleContract")
@Slf4j
public class SaleContractController {

    @Autowired
    private SaleContractService saleContractService;

    /**
     * 获取销售合同列表
     *
     * 该方法通过GET请求方式提供销售合同列表的数据接口
     * 主要用于前端页面展示销售合同列表数据
     *
     * @param saleContractDto 查询参数对象，用于筛选销售合同
     * @return 返回分页的销售合同列表数据，包括总记录数、当前页码、每页显示条数等信息
     */
    @GetMapping("/list")
    public YResult<PageResult<SaleContractVO>> getList(SaleContractDto saleContractDto) {
        return saleContractService.pageList(saleContractDto);
    }

    /**
     * 获取销售合同信息
     *
     * @param type 合同类型
     * @return 返回生成的销售合同代码
     */
    @GetMapping("/generate/code")
    public YResult<String> generateCode(String type) {
        return saleContractService.generateCode(type);
    }

    /**
     * 获取销售合同信息
     *
     * 通过GET请求方式，根据提供的销售合同ID，调用服务获取相应的销售合同详细信息
     *
     * @param id 销售合同的唯一标识符
     * @return 返回一个封装了销售合同信息的结果对象，包含成功状态和数据
     */
    @GetMapping("/info")
    public YResult<SaleContractInfoVO> getInfo(String id) {
        return saleContractService.getSaleContractById(id);
    }

    /**
     * 通过GET请求获取采购信息
     *
     * @param id 采购单据的唯一标识符
     * @return 返回一个包含销售合同采购信息的YResult对象
     */
    @GetMapping("/purchase/info")
    public YResult<SaleContractPurchaseInfoVO> getSaleContractPurchaseInfo(String id) {
        return saleContractService.getSaleContractPurchaseInfo(id);
    }

    /**
     * 保存销售合同信息
     *
     * 该方法用于接收前端发送的销售合同保存请求，并将请求体中的销售合同信息
     * 传递给服务层进行处理
     *
     * @param saveDto 请求体中的销售合同信息，包含需要保存的销售合同的详细数据
     * @return 返回一个包含操作结果的对象，其中包含了操作是否成功的信息
     */
    @PostMapping("/save")
    public YResult<String> saveInfo(@RequestBody SaleContractSaveDto saveDto) {
        return saleContractService.saveInfo(saveDto);
    }

    /**
     * 删除销售合同信息
     *
     * 此接口用于通过ID删除销售合同记录它使用POST请求，
     * 并期待一个包含销售合同ID的有效请求体
     *
     * @param saveDto 请求体，包含要删除的销售合同的ID
     * @return YResult<String> 删除操作的结果，包含操作信息的字符串
     */
    @PostMapping("/deleted")
    public YResult<String> deleted(@RequestBody @Validated SaleContractDeletedDto saveDto) {
        return saleContractService.deleted(saveDto.getId());
    }

    /**
     * 提交审批销售合同信息
     *
     * 该方法用于提交销售合同的审批申请，通过POST请求方式接收前端传来的审批信息，
     * 并对其进行有效性校验后，委托给销售合同服务进行后续的审批流程处理。
     *
     * @param approvalDto 销售合同提交审批的数据传输对象，通过RequestBody接收，
     *                   并通过Validated注解进行数据校验
     * @return 返回一个通用的结果对象，包含审批操作的结果信息
     */
    @PostMapping("/submit/approval")
    public YResult<String> submitApproval(@RequestBody @Validated SaleContractSubmitApprovalDto approvalDto) {
        return saleContractService.submitApproval(approvalDto);
    }

    /**
     * 审批销售合同
     *
     * 该方法接收一个销售合同审批数据传输对象（DTO），并对销售合同进行审批操作
     * 审批流程包括但不限于检查审批信息的合法性、完整性，以及可能的审批权限验证等
     * 具体的审批逻辑和规则由 {@link SaleContractService} 类的 {@code approval} 方法实现
     *
     * @param approvalDto 销售合同审批DTO，包含审批所需的各种信息
     * @return 返回一个包含审批结果的响应对象
     */
    @PostMapping("/approval")
    public YResult<String> approval(@RequestBody @Validated SaleContractApprovalDto approvalDto) {
        return saleContractService.approval(approvalDto);
    }


    /**
     * 撤销
     *
     * @return
     */
    @PostMapping("/revocation")
    public YResult<String> revocation() {
        return YResult.error("暂不支持");
    }





    /**
     * 导出文件
     *
     * @return
     */

    @GetMapping("/export/file")
    public YResult<String> exportFile(SaleContractDto saleContractDto,  HttpServletResponse response) {
        try {
            List<ContractExcelDto> contractMaterialExportDtoList =  saleContractService.export(saleContractDto);
            try {
                // 这里URLEncoder.encode可以防止中文乱码
                String fileName = URLEncoder.encode("saleContract", String.valueOf(StandardCharsets.UTF_8))+".xlsx";
//                response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
                //设置sheet名
                ExportParams params = new ExportParams();
                params.setSheetName("合同信息模版");
                //设置标题
//                params.setTitle("商品信息");
                // 这里需要设置不关闭流
                Workbook workbook = ExcelExportUtil.exportExcel(params, ContractExcelDto.class, contractMaterialExportDtoList);
                //输出流
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                workbook.write(bos);
                byte[] bytes = bos.toByteArray();
                bos.close();
                try {
                    FileInfoDto fileInfoDto = AliOssUtil.upload(bytes,
                            fileName, null);
                    if (null != fileInfoDto) {
                        return YResult.success(fileInfoDto.getLink());
                    } else {
                        return YResult.error("连接文件服务器失败，请重试");
                    }
                } catch (Exception e) {
                    return YResult.error("下载失败，请重试");
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }catch (Exception e) {
            log.error("导出合同信息失败",e);
        }
        return YResult.error("导出合同信息失败");
    }

}
